﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.Serialization;
//using System.Runtime.InteropServices;

namespace Pegasus.Collections.Generic
{
	/// <summary>
	/// Represents a collection of keys and values.  This class add the ability when using the index [] operator with a
	/// default value that is returned if the given key is not found.
	/// </summary>
	/// <typeparam name="TKey">The type of the keys in the dictionary.</typeparam>
	/// <typeparam name="TValue">The type of the values in the dictionary.</typeparam>
	[Serializable]
	[DebuggerDisplay( "Count = {Count}" )]
	public class DictionaryEx<TKey, TValue> : Dictionary<TKey, TValue>
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryEx&lt;TKey, TValue&gt;"/> class
		/// that is empty, has the default initial capacity, and uses the default equality comparer for the key type.
		/// </summary>
		public DictionaryEx()
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryEx&lt;TKey, TValue&gt;"/> class that
		/// contains elements copied from the specified IDictionaryand uses the default equality comparer
		/// for the key type.
		/// </summary>
		/// <param name="dictionary">The dictionary whose elements are copied to the new class.</param>
		public DictionaryEx( IDictionary<TKey, TValue> dictionary ) 
			: base( dictionary )
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryEx&lt;TKey, TValue&gt;"/> class that 
		/// is empty, has the default initial capacity, and uses the specified IEqualityComparer.
		/// </summary>
		/// <param name="comparer">The IEqualityComparer implementation to use when comparing keys.</param>
		public DictionaryEx( IEqualityComparer<TKey> comparer )
			: base( comparer )
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryEx&lt;TKey, TValue&gt;"/> class that 
		/// is empty, has the specified initial capacity, and uses the default equality comparer for the key type.
		/// </summary>
		/// <param name="capacity">The initial number of elements that the Dictionary can contain.</param>
		public DictionaryEx( int capacity )
			: base( capacity )
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryEx&lt;TKey, TValue&gt;"/> class that 
		/// contains elements copied from the specified IDictionary and uses the specified <see cref="IEqualityComparer&lt;T&gt;"/>
		/// equality comparer.
		/// </summary>
		/// <param name="dictionary"> The dictionary whose elements are copied to the new class.</param>
		/// <param name="comparer">The IEqualityComparer implementation to use when comparing keys.</param>
		public DictionaryEx( IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer )
			: base( dictionary, comparer )
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryEx&lt;TKey, TValue&gt;"/> class that 
		/// is empty, has the default initial capacity, and uses the specified <see cref="IEqualityComparer&lt;T&gt;"/>
		/// equality comparer.
		/// </summary>
		/// <param name="capacity">The capacity.</param>
		/// <param name="comparer">The comparer.</param>
		public DictionaryEx( int capacity, IEqualityComparer<TKey> comparer )
			: base( capacity, comparer )
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryEx&lt;TKey, TValue&gt;"/> class with serialized data.
		/// </summary>
		/// <param name="info">A SerializationInfo object containing the informationrequired to serialize the Dictionary.</param>
		/// <param name="context">A StreamingContext structure containing the source and destination of the serialized stream 
		/// associated with the System.Collections.Generic.Dictionary.</param>
		protected DictionaryEx( SerializationInfo info, StreamingContext context )
			: base( info, context )
		{
		}

		/// <summary>
		/// Gets the value with the specified key or the default value if the key does not exist.
		/// </summary>
		/// <value>The value from the dictionary if the key exist, otherwise the default value.</value>
		public TValue this[ TKey key, TValue defaultValue ]
		{
			get
			{
				TValue value;
				
				if( !this.TryGetValue( key, out value ) )
				{
					return defaultValue;
				}

				return value;
			}
		}
	}
}
